const { Schema } = require('koishi')

/**
 * @description 剑网三团队管理插件
 */
class Jx3TeamPlugin {
  /**
   * @param {object} ctx - Koishi上下文
   * @param {object} config - 插件配置
   */
  constructor(ctx, config) {
    this.ctx = ctx
    this.config = config
    
    // 获取API服务
    this.jx3Api = ctx.jx3Api
    if (!this.jx3Api) {
      throw new Error('请先安装并配置jx3-api插件')
    }
    
    this.registerCommands()
    this.registerSchedule()
  }
  
  /**
   * @description 注册命令
   */
  registerCommands() {
    const { ctx } = this
    
    // 创建团队
    ctx.command('jx3.团队.创建 <副本名>', '创建一个副本团队')
      .option('time', '-t <time:string> 开团时间 (如: 20:00)', { fallback: this.getDefaultTime() })
      .option('desc', '-d <desc:string> 团队描述', { fallback: '' })
      .option('size', '-s <size:number> 团队人数上限', { fallback: 10 })
      .userFields(['authority'])
      .channelFields(['id'])
      .action(async ({ session, options }, dungeonName) => {
        if (!dungeonName) return '请输入副本名称'
        if (!session.userId) return '无法识别您的用户ID'
        
        // 检查权限
        if (session.user.authority < 3) {
          return '权限不足，需要管理员权限才能创建团队'
        }
        
        try {
          // 创建新团队
          const teamId = await ctx.database.create('jx3_team', {
            dungeonName,
            leaderId: session.userId,
            channelId: session.channelId,
            startTime: this.parseTime(options.time),
            description: options.desc,
            maxSize: options.size,
            members: [{ userId: session.userId, roleName: '团长', joinTime: Date.now() }],
            status: 'recruiting',
            createdAt: Date.now()
          })
          
          return `团队创建成功！
【副本】${dungeonName}
【时间】${options.time}
【人数上限】${options.size}
【团队ID】${teamId}

请使用 jx3.团队.报名 ${teamId} 进行报名`
        } catch (error) {
          ctx.logger.error('创建团队失败:', error)
          return `创建失败: ${error.message}`
        }
      })
    
    // 报名团队
    ctx.command('jx3.团队.报名 <teamId:number>', '报名参加团队副本')
      .option('role', '-r <role:string> 角色名称', { fallback: '' })
      .userFields(['authority'])
      .channelFields(['id'])
      .action(async ({ session, options }, teamId) => {
        if (!teamId) return '请输入团队ID'
        if (!session.userId) return '无法识别您的用户ID'
        
        try {
          // 查询团队信息
          const teamInfo = await ctx.database.get('jx3_team', { id: teamId })
          if (!teamInfo || teamInfo.length === 0) {
            return '未找到该团队，请检查团队ID'
          }
          
          const team = teamInfo[0]
          
          // 检查团队状态
          if (team.status !== 'recruiting') {
            return '该团队不在招募状态，无法报名'
          }
          
          // 检查人数上限
          if (team.members.length >= team.maxSize) {
            return '该团队已达人数上限，无法报名'
          }
          
          // 检查是否已报名
          const alreadyJoined = team.members.some(member => member.userId === session.userId)
          if (alreadyJoined) {
            return '您已经报名该团队'
          }
          
          // 获取角色名
          let roleName = options.role
          if (!roleName) {
            // 尝试获取绑定角色
            const userBind = await ctx.database.get('jx3_user_bind', { userId: session.userId })
            if (userBind && userBind.length > 0) {
              roleName = userBind[0].roleName
            } else {
              roleName = '未绑定角色'
            }
          }
          
          // 更新团队成员
          const newMembers = [...team.members, {
            userId: session.userId,
            roleName,
            joinTime: Date.now()
          }]
          
          await ctx.database.set('jx3_team', { id: teamId }, {
            members: newMembers
          })
          
          return `报名成功！
【团队】${team.dungeonName}
【角色】${roleName}
【当前人数】${newMembers.length}/${team.maxSize}`
        } catch (error) {
          ctx.logger.error('报名团队失败:', error)
          return `报名失败: ${error.message}`
        }
      })
    
    // 查看团队信息
    ctx.command('jx3.团队.查看 <teamId:number>', '查看团队信息')
      .action(async ({ session }, teamId) => {
        if (!teamId) return '请输入团队ID'
        
        try {
          // 查询团队信息
          const teamInfo = await ctx.database.get('jx3_team', { id: teamId })
          if (!teamInfo || teamInfo.length === 0) {
            return '未找到该团队，请检查团队ID'
          }
          
          const team = teamInfo[0]
          return this.formatTeamInfo(team)
        } catch (error) {
          ctx.logger.error('查询团队信息失败:', error)
          return `查询失败: ${error.message}`
        }
      })
    
    // 关闭团队
    ctx.command('jx3.团队.关闭 <teamId:number>', '关闭团队招募')
      .userFields(['authority'])
      .action(async ({ session }, teamId) => {
        if (!teamId) return '请输入团队ID'
        if (!session.userId) return '无法识别您的用户ID'
        
        try {
          // 查询团队信息
          const teamInfo = await ctx.database.get('jx3_team', { id: teamId })
          if (!teamInfo || teamInfo.length === 0) {
            return '未找到该团队，请检查团队ID'
          }
          
          const team = teamInfo[0]
          
          // 检查权限
          if (team.leaderId !== session.userId && session.user.authority < 3) {
            return '权限不足，只有团长或管理员才能关闭团队'
          }
          
          // 更新团队状态
          await ctx.database.set('jx3_team', { id: teamId }, {
            status: 'closed',
            closedAt: Date.now()
          })
          
          return `团队已关闭招募
【副本】${team.dungeonName}
【人数】${team.members.length}/${team.maxSize}`
        } catch (error) {
          ctx.logger.error('关闭团队失败:', error)
          return `关闭失败: ${error.message}`
        }
      })
    
    // 团队列表
    ctx.command('jx3.团队.列表', '查看当前招募中的团队')
      .channelFields(['id'])
      .action(async ({ session }) => {
        try {
          // 查询当前频道的团队
          const teams = await ctx.database.get('jx3_team', {
            channelId: session.channelId,
            status: 'recruiting'
          })
          
          if (!teams || teams.length === 0) {
            return '当前没有正在招募的团队'
          }
          
          return this.formatTeamList(teams)
        } catch (error) {
          ctx.logger.error('查询团队列表失败:', error)
          return `查询失败: ${error.message}`
        }
      })
  }
  
  /**
   * @description 注册定时任务
   */
  registerSchedule() {
    const { ctx } = this
    
    // 团队开始提醒
    ctx.scheduler.every('1m', async () => {
      try {
        // 查询即将开始的团队
        const now = Date.now()
        const startBuffer = 15 * 60 * 1000 // 15分钟
        
        const teams = await ctx.database.get('jx3_team', {
          status: 'recruiting',
          startTime: { $lte: now + startBuffer, $gt: now }
        })
        
        for (const team of teams) {
          const timeLeft = Math.floor((team.startTime - now) / (60 * 1000))
          
          // 发送提醒
          await ctx.bots[0].sendMessage(team.channelId, `【团队即将开始】
副本: ${team.dungeonName}
时间: 还有${timeLeft}分钟
人数: ${team.members.length}/${team.maxSize}
ID: ${team.id}

请队员做好准备！`)
          
          // 更新提醒状态
          await ctx.database.set('jx3_team', { id: team.id }, {
            reminded: true
          })
        }
      } catch (error) {
        ctx.logger.error('团队提醒任务失败:', error)
      }
    })
  }
  
  /**
   * @description 格式化团队信息
   * @param {object} team - 团队信息
   * @returns {string} 格式化后的团队信息
   */
  formatTeamInfo(team) {
    const startTime = new Date(team.startTime)
    const startTimeStr = `${startTime.getMonth() + 1}月${startTime.getDate()}日 ${startTime.getHours()}:${String(startTime.getMinutes()).padStart(2, '0')}`
    
    let result = `团队信息：
【ID】${team.id}
【副本】${team.dungeonName}
【时间】${startTimeStr}
【状态】${team.status === 'recruiting' ? '招募中' : '已关闭'}
【人数】${team.members.length}/${team.maxSize}
${team.description ? `【说明】${team.description}` : ''}

【成员列表】`
    
    team.members.forEach((member, index) => {
      result += `
${index + 1}. ${member.roleName}`
    })
    
    return result
  }
  
  /**
   * @description 格式化团队列表
   * @param {Array} teams - 团队列表
   * @returns {string} 格式化后的团队列表
   */
  formatTeamList(teams) {
    let result = `当前招募中的团队（${teams.length}个）：\n`
    
    teams.forEach(team => {
      const startTime = new Date(team.startTime)
      const startTimeStr = `${startTime.getHours()}:${String(startTime.getMinutes()).padStart(2, '0')}`
      
      result += `
【ID】${team.id} - ${team.dungeonName}
【时间】${startTimeStr} 【人数】${team.members.length}/${team.maxSize}`
    })
    
    return result
  }
  
  /**
   * @description 获取默认开团时间（当天晚上8点）
   * @returns {string} 默认时间字符串
   */
  getDefaultTime() {
    return '20:00'
  }
  
  /**
   * @description 解析时间字符串为时间戳
   * @param {string} timeStr - 时间字符串 (格式: HH:MM)
   * @returns {number} 时间戳
   */
  parseTime(timeStr) {
    const now = new Date()
    const [hours, minutes] = timeStr.split(':').map(Number)
    
    const targetDate = new Date(now)
    targetDate.setHours(hours, minutes, 0, 0)
    
    // 如果设定时间已过，则设为明天
    if (targetDate < now) {
      targetDate.setDate(targetDate.getDate() + 1)
    }
    
    return targetDate.getTime()
  }
}

// 定义数据库模型
function applyModel(ctx) {
  // 团队数据表
  ctx.model.extend('jx3_team', {
    id: 'unsigned',
    dungeonName: 'string',
    leaderId: 'string',
    channelId: 'string',
    startTime: 'number',
    description: 'string',
    maxSize: 'unsigned',
    members: 'json',
    status: 'string',
    reminded: 'boolean',
    createdAt: 'number',
    closedAt: 'number'
  })
}

// 配置模式定义
const configSchema = Schema.object({})

// 插件主方法
module.exports.name = 'jx3-team'
module.exports.inject = ['database', 'jx3Api', 'scheduler']

module.exports.Config = configSchema

module.exports.apply = (ctx, config) => {
  // 应用数据库模型
  applyModel(ctx)
  
  // 创建插件实例
  ctx.plugin(Jx3TeamPlugin, config)
  
  ctx.on('ready', () => {
    ctx.logger.info('剑网三团队管理插件已启动')
  })
} 